package com.iwhalecloud.bss.kite.cucc.service.custview.evolve.task;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

import com.iwhalecloud.bss.kite.cucc.common.constant.LocalDcPublicConsts;
import com.iwhalecloud.bss.kite.cucc.common.constant.LocalKeyConsts;
import com.iwhalecloud.bss.kite.cucc.common.util.CommonUtil;
import com.iwhalecloud.bss.kite.cucc.service.util.ProdCateUtil;
import com.iwhalecloud.bss.kite.cucc.spec.impl.transfer.GoodsInfoTransfer;
import com.iwhalecloud.bss.kite.dataservice.cache.*;
import com.iwhalecloud.bss.kite.dataservice.entity.spec.Offer;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.tuple.Pair;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.iwhalecloud.bss.kite.common.constant.KeyConsts;
import com.iwhalecloud.bss.kite.common.util.KiteListUtils;
import com.iwhalecloud.bss.kite.common.util.KiteMapUtils;
import com.iwhalecloud.bss.kite.common.util.KiteStringUtils;
import com.iwhalecloud.bss.kite.cucc.client.dto.pos.KitePosAttrDTO;
import com.iwhalecloud.bss.kite.cucc.client.dto.pos.KitePosDTO;
import com.iwhalecloud.bss.kite.cucc.client.dto.pos.KitePosGoodsDTO;
import com.iwhalecloud.bss.kite.cucc.client.dto.pos.KitePosProductDTO;
import com.iwhalecloud.bss.kite.cucc.client.enumerate.PayableSuitServiceEnum;
import com.iwhalecloud.bss.kite.cucc.client.vo.custview.AddProductVO;
import com.iwhalecloud.bss.kite.cucc.client.vo.custview.BaseProductVO;
import com.iwhalecloud.bss.kite.cucc.client.vo.custview.CustViewAttr;
import com.iwhalecloud.bss.kite.cucc.client.vo.custview.CustViewBaseVO;
import com.iwhalecloud.bss.kite.cucc.client.vo.custview.CustViewVO;
import com.iwhalecloud.bss.kite.cucc.client.vo.custview.FeePlanVO;
import com.iwhalecloud.bss.kite.cucc.client.vo.custview.PayableSuit;
import com.iwhalecloud.bss.kite.cucc.client.vo.custview.PayableSuitServiceVO;
import com.iwhalecloud.bss.kite.cucc.client.vo.custview.ProductFuncVO;
import com.iwhalecloud.bss.kite.cucc.client.vo.custview.ProductInfoVO;
import com.iwhalecloud.bss.kite.cucc.client.vo.custview.ProductVO;
import com.iwhalecloud.bss.kite.cucc.service.attr.LocalAttrHelper;
import com.iwhalecloud.bss.kite.dataservice.api.IQueryProductService;
import com.iwhalecloud.bss.kite.dataservice.entity.AttrValue;
import com.iwhalecloud.bss.kite.dataservice.entity.DcPublic;
import com.iwhalecloud.bss.kite.dataservice.entity.spec.ProdAttr;
import com.iwhalecloud.bss.kite.dataservice.entity.spec.Product;
import com.iwhalecloud.bss.kite.manager.enums.RelType;

import com.ztesoft.bss.common.util.SpringUtil;

/**
 * @ClassName : ProductInfoTask
 * @Description :
 * @Author : xie.zhengjun
 * @Date : 2021/4/30 18:54
 */
public class ProductInfoTask extends AbstractCustViewTask{
    @Override
    public CustViewBaseVO call(Object[] args) {
        if (args.length != 3) {
            return null;
        }
        KitePosDTO kitePosDTO = (KitePosDTO) args[0];
        CustViewVO custViewVO = (CustViewVO) args[1];
        Map<String, Object> userDetail = (Map) args[2];
        BaseProductVO baseProductVO = new BaseProductVO();
        AddProductVO addProductVO = new AddProductVO();
        ProductInfoVO productInfoVO = new ProductInfoVO();
        productInfoVO.setBaseProductVO(baseProductVO);
        productInfoVO.setAddProductVO(addProductVO);
        custViewVO.setProduct(productInfoVO);
        List<KitePosGoodsDTO> goods = kitePosDTO.getGoods();
        if (KiteListUtils.isEmpty(goods)) {
            return productInfoVO;
        }

        for (KitePosGoodsDTO good : goods) {
            List<KitePosProductDTO> products = good.getProducts();
            if (KiteListUtils.isEmpty(products)) {
                continue;
            }
            if(!GoodsInfoTransfer.isAddRoleOffer(good.getCode(),"1")){
                productInfoVO.setGoodId(good.getCatagoryId());
            }
            // 先默认一个goods下只有一个产品
            KitePosProductDTO kitePosProductDTO = products.get(0);
            String prodType = kitePosProductDTO.getType();
            // 基础产品
            if (KiteStringUtils.isEqual(prodType, "base")) {
                assembleBaseProduct(baseProductVO, kitePosProductDTO, userDetail);
            }
            // 附加产品
            else if (KiteStringUtils.isEqual(prodType, "add")) {
                assembleAddProduct(addProductVO, kitePosProductDTO);
            }
        }
        return productInfoVO;
    }

    /**
     * 组装基础产品
     *
     * @param baseProductVO
     * @param kitePosProductDTO
     */
    private void assembleBaseProduct(BaseProductVO baseProductVO, KitePosProductDTO kitePosProductDTO, Map<String, Object> userDetail) {
        // 基础产品的属性
        List<CustViewAttr> baseProductAttrs = new ArrayList<>();
        // apn
        List<ProductFuncVO> apns = new ArrayList<>();
        // 通信计划
        List<ProductFuncVO> communicationPlans = new ArrayList<>();
        // 资费计划
        List<FeePlanVO> feePlans = new ArrayList<>();
        // 5G切片
        List<ProductFuncVO> fifthGenSlices = new ArrayList<>();
        // 承诺
        List<CustViewAttr> promise = new ArrayList<>();
        baseProductVO.setAttrs(baseProductAttrs);
        baseProductVO.setApns(apns);
        baseProductVO.setCommunicationPlans(communicationPlans);
        baseProductVO.setFeePlans(feePlans);
        baseProductVO.setFifthGenSlices(fifthGenSlices);
        baseProductVO.setPromise(promise);
        // 定制类资费计划-基础信息
        List<Pair<String, List<CustViewAttr>>> feePlanBaseInfoPairs = new ArrayList<>();
        // 定制类资费计划-服务信息
        List<Pair<String, List<CustViewAttr>>> feePlanServiceInfoPairs = new ArrayList<>();
        // 定制类资费计划-折扣信息
        List<Pair<String, List<CustViewAttr>>> feePlanDiscountInfoPairs = new ArrayList<>();

        // 是否五大双线落地方产品
        boolean flag = false;
        String offerId = null;
        List<Map<String, Object>> goods = CommonUtil.getList(userDetail, "USER_GOODS_INFOS");
        if(KiteListUtils.isNotEmpty(goods)) {
            offerId = MapUtils.getString(goods.get(0), "GOODS_ID");
        }
        String offerIdStr = offerId;
        if(KiteStringUtils.isNotEmpty(offerIdStr)) {
            List<DcPublic> list = DcPublicCache.get("20210719001");
            flag = (list != null) && list.stream().anyMatch(dcPublic -> KiteStringUtils.isEqual(offerIdStr, dcPublic.getCodeb()));
        }
        boolean flagBool = flag;

        Map<String, String> addrMap = new HashMap<>();
        // 处理报文返回的产品节点的属性和属性组
        Optional.ofNullable(kitePosProductDTO.getAttrs())
            .ifPresent(kitePosAttrDTOS -> kitePosAttrDTOS.forEach(kitePosAttrDTO -> {
                String baseProdId = kitePosProductDTO.getCode();
                // 处理产品属性
                if (KiteStringUtils.isEqual(kitePosAttrDTO.getType(), "String")) {
                    // 2_0000211 A端无名装机地址 2_0000117 Z端无名装机地址
                    if (KiteStringUtils.equalsAny(kitePosAttrDTO.getCode(), "2_0000211", "2_0000117")) {
                        addrMap.put(kitePosAttrDTO.getCode(), kitePosAttrDTO.getValue());
                    }
                    baseProductAttrs.add(getProdAttr(baseProdId, kitePosAttrDTO, offerIdStr, flagBool));
                }
                // 处理属性组
                else if (KiteStringUtils.isEqual(kitePosAttrDTO.getType(), "ATTR_GROUP")) {
                    String groupAttrCode = kitePosAttrDTO.getCode();
                    // 主产品下面的属性组是功能产品，属性组的code就是该功能产品的prod_id
                    String value = kitePosAttrDTO.getValue();
                    // map 为产品的 实例标识（接口过来的） 和 属性集 构成的键值对
                    Map<String, JSONArray> map = JSON.parseObject(value, Map.class);
                    if (KiteMapUtils.isEmpty(map)) {
                        return;
                    }
                    // 遍历产品实例 注意，这里的产品都是同一种
                    map.forEach((s, attrJsons) -> {
                        List<CustViewAttr> attrs = new ArrayList<>();
                        // apn
                        if (KiteStringUtils.isEqual(groupAttrCode, "300000150")) {
                            if (KiteStringUtils
                                .equalsAny(baseProdId, ProdCateUtil.getMainMemberProdIdForArr(ProdCateUtil.TY5G_PROD, ProdCateUtil.TYNB_PROD, ProdCateUtil.TYCAT1_PROD, ProdCateUtil.TY4G_PROD))) {
                                // 通用类的APN和通信计划的属性用的是主产品的
                                fillAttrsNew(baseProdId, attrJsons, attrs);
                            }
                            else {
                                // 定制类apn
                                String prodId = getProdIdForLinkageConfig("apn", baseProdId);
                                fillAttrsNew(prodId, attrJsons, attrs);
                            }
                            attrs.sort(Comparator.comparing(CustViewAttr::getOrderId));
                            ProductFuncVO productFuncVO = new ProductFuncVO();
                            productFuncVO.setFamilyName("APN");
                            productFuncVO.setAttrs(attrs);
                            apns.add(productFuncVO);
                        }
                        // 通信计划
                        else if (KiteStringUtils.equalsAny(groupAttrCode, "300000151", LocalKeyConsts.FUNC_PROD_ID_YF5GTX)) {
                            if (KiteStringUtils
                                .equalsAny(baseProdId, ProdCateUtil.getMainMemberProdIdForArr(ProdCateUtil.TY5G_PROD, ProdCateUtil.TYNB_PROD, ProdCateUtil.TYCAT1_PROD, ProdCateUtil.TY4G_PROD))) {
                                // 通用类的APN和通信计划的属性用的是主产品的
                                fillAttrsNew(baseProdId, attrJsons, attrs);
                            }
                            else {
                                // 定制类通信计划
                                String prodId = getProdIdForLinkageConfig("communicationPlan", baseProdId);
                                fillAttrsNew(prodId, attrJsons, attrs);
                            }
                            attrs.sort(Comparator.comparing(CustViewAttr::getOrderId));
                            ProductFuncVO productFuncVO = new ProductFuncVO();
                            productFuncVO.setFamilyName("通信计划");
                            productFuncVO.setAttrs(attrs);
                            communicationPlans.add(productFuncVO);
                        }
                        // 通用类资费计划
                        else if (KiteStringUtils.isEqual(groupAttrCode, "300000152")) {
                            String prodId = getProdIdForLinkageConfig("feePlan", baseProdId);
                            fillAttrsNew(prodId, attrJsons, attrs);
                            attrs.sort(Comparator.comparing(CustViewAttr::getOrderId));
                            FeePlanVO feePlanVO = new FeePlanVO();
                            feePlanVO.setFamilyName("资费计划");
                            feePlanVO.setBaseInfo(attrs);
                            feePlans.add(feePlanVO);
                        }
                        // 定制类资费计划-基础信息
                        else if (KiteStringUtils.equalsAny(groupAttrCode, "300000170", LocalKeyConsts.FUNC_PROD_ID_YF5GZF_BASE)) {
                            Optional.ofNullable(getProduct(baseProdId, groupAttrCode))
                                .ifPresent(product1 -> fillAttrsNew(product1.getProdId(), attrJsons, attrs));
                            attrs.sort(Comparator.comparing(CustViewAttr::getOrderId));
                            String feePlanId = attrs.stream()
                                .filter(custViewAttr -> KiteStringUtils.isEqual(custViewAttr.getCode(), "200004129"))
                                .findFirst().map(CustViewAttr::getValue).orElse("");
                            if (KiteStringUtils.isNotEmpty(feePlanId)) {
                                feePlanBaseInfoPairs.add(Pair.of(feePlanId, attrs));
                            }
                        }
                        // 定制类资费计划-服务信息
                        else if (KiteStringUtils.equalsAny(groupAttrCode, "300000171", LocalKeyConsts.FUNC_PROD_ID_YF5GZF_FW)) {
                            Optional.ofNullable(getProduct(baseProdId, groupAttrCode))
                                .ifPresent(product1 -> fillAttrsNew(product1.getProdId(), attrJsons, attrs));
                            attrs.sort(Comparator.comparing(CustViewAttr::getOrderId));
                            String feePlanId = attrs.stream()
                                .filter(custViewAttr -> KiteStringUtils.isEqual(custViewAttr.getCode(), "200004145"))
                                .findFirst().map(CustViewAttr::getValue).orElse("");
                            if (KiteStringUtils.isNotEmpty(feePlanId)) {
                                feePlanServiceInfoPairs.add(Pair.of(feePlanId, attrs));
                            }
                        }
                        // 定制类资费计划-折扣信息
                        else if (KiteStringUtils.equalsAny(groupAttrCode, "300000172", LocalKeyConsts.FUNC_PROD_ID_YF5GZF_ZK)) {
                            Optional.ofNullable(getProduct(baseProdId, groupAttrCode))
                                .ifPresent(product1 -> fillAttrsNew(product1.getProdId(), attrJsons, attrs));
                            attrs.sort(Comparator.comparing(CustViewAttr::getOrderId));
                            String feePlanId = attrs.stream()
                                .filter(custViewAttr -> KiteStringUtils.isEqual(custViewAttr.getCode(), "200004146"))
                                .findFirst().map(CustViewAttr::getValue).orElse("");
                            if (KiteStringUtils.isNotEmpty(feePlanId)) {
                                feePlanDiscountInfoPairs.add(Pair.of(feePlanId, attrs));
                            }
                        }
                        // 5G切片
                        else if (KiteStringUtils.isEqual(groupAttrCode, "300000159")) {
                            String prodId = getProdIdForLinkageConfig("5GSlice", baseProdId);
                            fillAttrsNew(prodId, attrJsons, attrs);
                            attrs.sort(Comparator.comparing(CustViewAttr::getOrderId));
                            ProductFuncVO productFuncVO = new ProductFuncVO();
                            productFuncVO.setFamilyName("5G切片");
                            productFuncVO.setAttrs(attrs);
                            fifthGenSlices.add(productFuncVO);
                        }
                        // 承诺
                        else if (KiteStringUtils.isEqual(groupAttrCode, "300000167")) {
                            fillAttrsNew(baseProdId, attrJsons, attrs);
                            promise.addAll(attrs);
                        }
                    });
                }
            }));

        if(!flag) {
            // 2_0000209 装机地址 2_0000105 Z端装机地址
            baseProductAttrs.stream()
                .filter(custViewAttr -> KiteStringUtils.isEqual(custViewAttr.getCode(), "2_0000209"))
                .findFirst().ifPresent(custViewAttr -> custViewAttr.setValueDesc(addrMap.get("2_0000211")));
            baseProductAttrs.stream()
                .filter(custViewAttr -> KiteStringUtils.isEqual(custViewAttr.getCode(), "2_0000105"))
                .findFirst().ifPresent(custViewAttr -> custViewAttr.setValueDesc(addrMap.get("2_0000117")));
        }
        baseProductAttrs.sort(Comparator.comparing(CustViewAttr::getOrderId));
        assembleCustomizedFeePlan(feePlans, feePlanBaseInfoPairs, feePlanServiceInfoPairs, feePlanDiscountInfoPairs);
    }

    private String getProdIdForLinkageConfig(String prodType, String baseProdId) {
        List<DcPublic> dcPublics = DcPublicCache.getByPcode("2021022301", prodType, baseProdId);
        return dcPublics.stream().findFirst().map(DcPublic::getCodea).orElse("");
    }

    private void fillAttrsNew(String prodId, JSONArray attrJsons, List<CustViewAttr> attrs) {
        attrJsons.forEach(attrJson -> {
            // 每个产品的单个属性处理
            KitePosAttrDTO kitePosAttrDTO = JSON.parseObject(JSON.toJSONString(attrJson), KitePosAttrDTO.class);
            if (KiteStringUtils.isEqual(kitePosAttrDTO.getType(), "String")) {
                attrs.add(getProdAttr(prodId, kitePosAttrDTO, null, false));
            }
        });
    }

    /**
     * 获取某个属性组代表的产品
     *
     * @param baseProdId    主产品标识
     * @param groupAttrCode 属性组code
     * @return 属性组代表的产品
     */
    private Product getProduct(String baseProdId, String groupAttrCode) {
        String baseOfferId = Optional.ofNullable(ProductCache.get(baseProdId)).map(Product::getBaseOfferId).orElse("");
        return Optional.ofNullable(
            SpringUtil.getBean(IQueryProductService.class).getProdByBaseOfferIdAndProdNbr(baseOfferId, groupAttrCode))
            .orElse(getfeePlanFunc(baseProdId, groupAttrCode));
    }

    /**
     * 获取资费计划的功能产品
     *
     * @param baseProdId    主产品标识
     * @param groupAttrCode 属性组code
     * @return 资费计划的功能产品(基础信息 / 服务信息 / 折扣信息)
     */
    private Product getfeePlanFunc(String baseProdId, String groupAttrCode) {
        List<String> feePlanProdIds = Optional.ofNullable(ProdAttrCache.get(baseProdId)).map(
            prodAttrs -> prodAttrs.stream()
                .filter(prodAttr -> KiteStringUtils.isEqual(prodAttr.getAttrValueTypeId(), KeyConsts.GEN_LOGIC))
                .map(ProdAttr::getGroupId).filter(groupId -> KiteStringUtils
                    .isEqual(Optional.ofNullable(ProductCache.get(groupId)).map(Product::getProdFuncType).orElse(""),
                        KeyConsts.PROD_FUNC_TYPE_101)).collect(Collectors.toList())).orElse(new ArrayList<>());
        Product feePlanFunc = null;
        for (String feePlanProdId : feePlanProdIds) {
            feePlanFunc = Optional
                .ofNullable(ProdRelCache.getByA(feePlanProdId, RelType.PROD_REL_TYPE_100600.getCode())).flatMap(
                    products -> products.stream()
                        .filter(product -> KiteStringUtils.isEqual(product.getProdNbr(), groupAttrCode)).findFirst())
                .orElse(null);
            if (Objects.nonNull(feePlanFunc)) {
                break;
            }
        }
        return feePlanFunc;
    }

    /**
     * 组装定制类产品的资费计划
     *
     * @param feePlans
     * @param feePlanBaseInfoPairs
     * @param feePlanServiceInfoPairs
     * @param feePlanDiscountInfoPairs
     */
    private void assembleCustomizedFeePlan(List<FeePlanVO> feePlans,
        List<Pair<String, List<CustViewAttr>>> feePlanBaseInfoPairs,
        List<Pair<String, List<CustViewAttr>>> feePlanServiceInfoPairs,
        List<Pair<String, List<CustViewAttr>>> feePlanDiscountInfoPairs) {
        for (Pair<String, List<CustViewAttr>> feePlanBaseInfoPair : feePlanBaseInfoPairs) {
            FeePlanVO feePlanVO = new FeePlanVO();
            feePlanVO.setBaseInfo(feePlanBaseInfoPair.getRight());
            feePlanVO.setServiceInfos(feePlanServiceInfoPairs.stream().filter(feePlanServiceInfoPair -> KiteStringUtils
                .isEqual(feePlanBaseInfoPair.getLeft(), feePlanServiceInfoPair.getLeft())).map(Pair::getRight)
                .collect(Collectors.toList()));
            feePlanVO.setDiscountInfo(feePlanDiscountInfoPairs.stream().filter(
                feePlanDiscountInfoPair -> KiteStringUtils
                    .isEqual(feePlanBaseInfoPair.getLeft(), feePlanDiscountInfoPair.getLeft())).map(Pair::getRight)
                .findFirst().orElse(null));
            feePlanVO.setFamilyName("资费计划");
            feePlans.add(feePlanVO);
        }
    }

    /**
     * 组装附加产品
     *
     * @param addProductVO
     * @param kitePosProductDTO
     */
    private void assembleAddProduct(AddProductVO addProductVO, KitePosProductDTO kitePosProductDTO) {
        String prodId = kitePosProductDTO.getCode();
        if (KiteStringUtils.isEqual(prodId, "100000000015947")) {
            // 可付费套包
            assemblePayableSuit(addProductVO, kitePosProductDTO);
        }
        else if (KiteStringUtils.equalsAny(prodId, "100000000015946", "60000039")) {
            // 测试套包 或 雁飞加油站税控-维护服务
            assembleTestSuit(addProductVO, kitePosProductDTO);
        }
        else if (KiteStringUtils.isEqual(prodId, "100000000015945")) {
            // 补充通信套包 （属性组实现）
            assembleAddSuit(addProductVO, kitePosProductDTO);
        }
    }

    /**
     * 组装可付费套包
     *
     * @param addProductVO      附加产品视图对象
     * @param kitePosProductDTO 接口返回的产品节点
     */
    private void assemblePayableSuit(AddProductVO addProductVO, KitePosProductDTO kitePosProductDTO) {
        String prodId = kitePosProductDTO.getCode();
        List<PayableSuitServiceVO> payableSuitServices = new ArrayList<>();
        PayableSuit payableSuit = new PayableSuit();
        payableSuit.setPayableSuitServices(payableSuitServices);
        payableSuit.setFamilyName("可付费套包");
        addProductVO.setPayableSuit(payableSuit);
        // 收集可付费套包的属性
        List<CustViewAttr> payableSuitAttrs = new ArrayList<>();
        Optional.ofNullable(kitePosProductDTO.getAttrs())
            .ifPresent(kitePosAttrDTOS -> kitePosAttrDTOS.forEach(kitePosAttrDTO -> {
                if (KiteStringUtils.isEqual(kitePosAttrDTO.getType(), "String")) {
                    payableSuitAttrs.add(getProdAttr(prodId, kitePosAttrDTO, null, false));
                }
            }));
        if (KiteListUtils.isNotEmpty(payableSuitAttrs)) {
            // 将可付费套包的属性分组处理，每一种服务的相关属性都在同一组下，groupId实际上是prod_attr_ext表的attr_id
            Map<String, List<CustViewAttr>> payableSuitAttrGroups = payableSuitAttrs.stream()
                .collect(Collectors.groupingBy(CustViewAttr::getGroupId));
            if (KiteMapUtils.isNotEmpty(payableSuitAttrGroups)) {
                payableSuitAttrGroups.forEach((groupId, custViewAttrs) -> {
                    PayableSuitServiceEnum payableSuitServiceEnum = PayableSuitServiceEnum
                        .valueOf("SERVICE_" + groupId);
                    PayableSuitServiceVO payableSuitServiceVO = new PayableSuitServiceVO();
                    payableSuitServiceVO.setServiceName(payableSuitServiceEnum.getServiceName());
                    for (CustViewAttr custViewAttr : custViewAttrs) {
                        if (KiteStringUtils.isEqual(custViewAttr.getCode(), payableSuitServiceEnum.getIsSelected())) {
                            payableSuitServiceVO.setIsSelected(custViewAttr.getValueDesc());
                        }
                        else if (KiteStringUtils
                            .isEqual(custViewAttr.getCode(), payableSuitServiceEnum.getStdPrice())) {
                            payableSuitServiceVO.setStdPrice(custViewAttr.getValueDesc());
                        }
                        else if (KiteStringUtils
                            .isEqual(custViewAttr.getCode(), payableSuitServiceEnum.getFinalPrice())) {
                            payableSuitServiceVO.setFinalPrice(custViewAttr.getValueDesc());
                        }
                        else if (KiteStringUtils
                            .isEqual(custViewAttr.getCode(), payableSuitServiceEnum.getDiscount())) {
                            payableSuitServiceVO.setDiscount(custViewAttr.getValueDesc());
                        }
                        else if (KiteStringUtils.isEqual(custViewAttr.getCode(), payableSuitServiceEnum.getRemark())) {
                            payableSuitServiceVO.setRemark(custViewAttr.getValueDesc());
                        }
                    }
                    payableSuitServices.add(payableSuitServiceVO);
                });
            }
        }
    }

    /**
     * 组装测试套包
     *
     * @param addProductVO      附加产品视图对象
     * @param kitePosProductDTO 接口返回的产品节点
     */
    private void assembleTestSuit(AddProductVO addProductVO, KitePosProductDTO kitePosProductDTO) {
        String prodId = kitePosProductDTO.getCode();
        ProductVO testSuit = new ProductVO();
        testSuit.setFamilyName(ProductCache.get(prodId).getProdName());
        List<CustViewAttr> testSuitAttrs = new ArrayList<>();
        testSuit.setAttrs(testSuitAttrs);
        Optional.ofNullable(kitePosProductDTO.getAttrs())
            .ifPresent(kitePosAttrDTOS -> kitePosAttrDTOS.forEach(kitePosAttrDTO -> {
                if (KiteStringUtils.isEqual(kitePosAttrDTO.getType(), "String")) {
                    testSuitAttrs.add(getProdAttr(prodId, kitePosAttrDTO, null, false));
                }
            }));
        addProductVO.setTestSuit(testSuit);
    }

    /**
     * 组装补充通信套包
     *
     * @param addProductVO      附加产品视图对象
     * @param kitePosProductDTO 接口返回的产品节点
     */
    private void assembleAddSuit(AddProductVO addProductVO, KitePosProductDTO kitePosProductDTO) {
        String prodId = kitePosProductDTO.getCode();
        List<ProductVO> addSuits = new ArrayList<>();
        addProductVO.setAddSuits(addSuits);
        Optional.ofNullable(kitePosProductDTO.getAttrs())
            .ifPresent(kitePosAttrDTOS -> kitePosAttrDTOS.forEach(kitePosAttrDTO -> {
                // 处理属性组
                if (KiteStringUtils.isEqual(kitePosAttrDTO.getType(), "ATTR_GROUP")) {
                    Optional.ofNullable(ProductCache.get(prodId)).ifPresent(product -> {
                        String value = kitePosAttrDTO.getValue();
                        // map 为产品的 实例标识（接口过来的） 和 属性集 构成的键值对
                        Map<String, JSONArray> map = JSON.parseObject(value, Map.class);
                        if (KiteMapUtils.isNotEmpty(map)) {
                            // 遍历产品实例 注意，这里的产品都是同一种
                            map.forEach((s, attrJsons) -> {
                                List<CustViewAttr> attrs = new ArrayList<>();
                                // 对单个产品属性集进行遍历
                                attrJsons.forEach(attrJson -> {
                                    // 每个产品的单个属性处理
                                    KitePosAttrDTO kitePosAttrDTO1 = JSON
                                        .parseObject(JSON.toJSONString(attrJson), KitePosAttrDTO.class);
                                    if (KiteStringUtils.isEqual(kitePosAttrDTO1.getType(), "String")) {
                                        attrs.add(getProdAttr(product.getProdId(), kitePosAttrDTO1, null, false));
                                    }
                                });
                                attrs.sort(Comparator.comparing(CustViewAttr::getOrderId));
                                ProductVO addSuit = new ProductVO();
                                addSuit.setFamilyName("补充通信套包");
                                addSuit.setAttrs(attrs);
                                addSuits.add(addSuit);
                            });
                        }
                    });
                }
            }));
    }

    /**
     * 转换单个产品属性
     *
     * @param prodId
     * @param kitePosAttrDTO
     * @return
     */
    private CustViewAttr getProdAttr(String prodId, KitePosAttrDTO kitePosAttrDTO, String offerId, boolean isFallProduct) {
        String fieldName = kitePosAttrDTO.getCode();
        CustViewAttr custViewAttr = new CustViewAttr(fieldName, kitePosAttrDTO.getValue());
        // 非常重要，因为属性要排序，orderId为空的话会导致排序报错进而整个属性列表会没掉
        custViewAttr.setOrderId("999");

        ProdAttr prodAttr = null;
        List<ProdAttr> attrs = (KiteStringUtils.isEmpty(offerId)) ? ProdAttrCache.get(prodId) : ProdAttrCache.getByOfferId(offerId, prodId);
        if(KiteListUtils.isNotEmpty(attrs)) {
            prodAttr = attrs.stream().filter(d -> fieldName.equals(d.getFieldName())).findAny().orElse(null);
        }

        if (Objects.isNull(prodAttr)) {
            return custViewAttr;
        }
        boolean flag=false;
        // 设置前端展示的属性名称
        custViewAttr.setName(prodAttr.getCname());
        custViewAttr.setGroupId(prodAttr.getGroupId());
        custViewAttr.setOrderId(KiteStringUtils.isEmpty(prodAttr.getOrderId()) ? "999" : prodAttr.getOrderId());
        List<DcPublic> dcPublics = DcPublicCache.getByPcode(LocalDcPublicConsts.DC_20211809001, prodAttr.getProductId(),prodAttr.getFieldName());
        if (!KiteListUtils.isEmpty(dcPublics)) {
            flag=true;
        }
        if (KiteStringUtils.equalsAny(prodAttr.getAttrValueTypeId(), KeyConsts.DROPDOWN, KeyConsts.RADIO)||flag) {
            // 如果是下拉框，需要翻译下拉值
            if (KiteStringUtils
                .equalsAny(prodAttr.getFieldName(), "2_0000220", "2_0000221", "2_0000222", "2_0000107", "2_0000109",
                    "2_0000111")||flag || (isFallProduct && KiteStringUtils.equalsAny(prodAttr.getFieldName(), "2_0000104","2_0000209","210005122","2_0000105"))) {
                // 省、地市、区县
                String regionName = LocalAttrHelper.getRegionName(kitePosAttrDTO.getValue());
                custViewAttr.setValueDesc(KiteStringUtils.isEmpty(regionName) ? kitePosAttrDTO.getValue() : regionName);
            }
            else {
                custViewAttr.setValueDesc(
                    Optional.ofNullable(AttrValueCache.getAttrValue(prodAttr.getAttrId(), kitePosAttrDTO.getValue()))
                        .map(AttrValue::getAttrValueName).orElse(kitePosAttrDTO.getValue()));
            }
        }
        else {
            custViewAttr.setValueDesc(kitePosAttrDTO.getValue());
        }
        // 业务开通范围
        if (KiteStringUtils.isEqual(fieldName, "200004172")) {
            custViewAttr.setValueDesc(KiteStringUtils.isEqual(kitePosAttrDTO.getValue(), "09") ?
                "全国" :
                LocalAttrHelper.getRegionName(kitePosAttrDTO.getValue()));
        }
        return custViewAttr;
    }
}
